package com.tmc.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

public class DateUtil {

	public static String yyyyMMddHHmmss = "yyyyMMddHHmmss";
	public static String yyyy_MM_dd = "yyyy-MM-dd";
	public static String yyyyMMdd = "yyyyMMdd";
	public static String yyyy_M_d = "yyyy-M-d";
	public static long Day2Long = 1000000 ;
	
	public static String toStrDate(Date date) {
		return toStrDate(date, yyyyMMddHHmmss);
	}

	public static String toStrDate(Date date, String format) {
		if (date == null) {
			return "";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(date);
	}
	
	public static String toStrDate(Long date, String format) throws ParseException{
		if (date == null) {
			return "";
		}
		SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmss);
		Date real = sdf.parse(date + "");
		return toStrDate(real, format);
	}

	public static Long toLongDate(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(yyyyMMddHHmmss);
		return Long.valueOf(sdf.format(date));
	}
	
	public static Long toLongDate(Date date, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return Long.valueOf(sdf.format(date));
	}
	
	public static String addDay(Date date, int number){
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH,number);
		return toStrDate(calendar.getTime(),"yyyy-MM-dd");
	}
	
	public static String addDay(Date date, int number, String format){
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH,number);
		return toStrDate(calendar.getTime(),format);
	}
	
	public static Date addDate(Date date, int number) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, number);// 鎶婃棩鏈熷線鍚庡鍔犱竴澶�.鏁存暟寰�鍚庢帹,璐熸暟寰�鍓嶇Щ鍔�?
		return calendar.getTime(); // 杩欎釜鏃堕棿灏辨槸鏃ユ湡寰�鍚庢帹涓�澶╃殑缁撴�?
	}
	
    public static String addDate(Date date, int number,String format){
    	return toStrDate(addDate(date, number),format);
    }
	
	public static Date addSecond(Date date, int number) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, number);// 鎶婃棩鏈熷線鍚庡鍔犵.鏁存暟寰�鍚庢帹,璐熸暟寰�鍓嶇Щ鍔�?
		return calendar.getTime(); // 杩欎釜鏃堕棿灏辨槸鏃ユ湡寰�鍚庢帹涓�澶╃殑缁撴�?
	}

	public static Date addMonth(Date date, int number) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.MONTH, number);// 鎶婃棩鏈熷線鍚庡鍔犱竴鏈�.鏁存暟寰�鍚庢帹,璐熸暟寰�鍓嶇Щ鍔�?
		return calendar.getTime(); // 杩欎釜鏃堕棿灏辨槸鏃ユ湡寰�鍚庢帹涓�鏈堢殑缁撴�?
	}

	public static Date addYear(Date date, int number) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, number);// 鎶婃棩鏈熷線鍚庡鍔犱竴骞�.鏁存暟寰�鍚庢帹,璐熸暟寰�鍓嶇Щ鍔�?
		return calendar.getTime(); // 杩欎釜鏃堕棿灏辨槸鏃ユ湡寰�鍚庢帹涓�骞寸殑缁撴�?
	}

	public static Long toLongDate(String date) {
		date = date.replaceAll("-", "").replaceAll(":", "");
		return toLongDate(date, yyyyMMddHHmmss);
	}

	public static Long toLongDate(String dateStr, String Format) {
		if (dateStr == null || "".equals(dateStr)) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(Format);
		Date date = null;
		try {
			date = sdf.parse(dateStr);
		} catch (ParseException e) {
		}
		return toLongDate(date);
	}

	public static String toStrDate(String data, String time) {
		return data + "T" + time + ":00";
	}
	
	// 15JUL
	public static String getMonthDayStr(String str, String deadline) {
		if (ObjectUtil.noText(str)) {
			return "";
		}
		int currentYear = Integer.valueOf(deadline.split("-")[0]);
		Integer day = Integer.valueOf(str.substring(0, 2));
		Integer month = Integer.valueOf(getMonthNum(str.substring(2, 5)));
		if (isBefore(currentYear + "-" + month + "-" + day, deadline)) {
			currentYear++;
		}
		return "" + currentYear + "-" + month + "-" + day;
	}							

	public static int getCurrentYear(){
		return Calendar.getInstance().get(Calendar.YEAR);
	}
	
	// 15JUL
	public static String getMonthDayStr(String str, int currentYear) {
		if (ObjectUtil.noText(str)) {
			return "";
		}
		if (currentYear < 100){
				currentYear = 2000 + currentYear;
		}
		Integer day = Integer.valueOf(str.substring(0, 2));
		Integer month = Integer.valueOf(getMonthNum(str.substring(2, 5)));
		return "" + currentYear + "-" + month + "-" + day;
	}
		
	public static String getMonthDayStr(String str) {
		if (str.indexOf(" ") > -1){
			return getMonthDayStr(str.split(" ")[0], Integer.valueOf(str.split(" ")[1]));
		}
		return getMonthDayStr(str, DateUtil.toStrDate(new Date(), DateUtil.yyyy_MM_dd));
	}	
	
	private static String getMonthNum(String month) {
		switch (month) {
		case "JAN":
			return "01";
		case "FEB":
			return "02";
		case "MAR":
			return "03";
		case "APR":
			return "04";
		case "MAY":
			return "05";
		case "JUN":
			return "06";
		case "JUL":
			return "07";
		case "AUG":
			return "08";
		case "SEP":
			return "09";
		case "OCT":
			return "10";
		case "NOV":
			return "11";
		case "DEC":
			return "12";
		}
		return "";
	}
	
	public static Date format(String date, String format) throws ParseException{
		if (ObjectUtil.noText(date)) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.parse(date);
	}
	
	public static Calendar calendarFormat(String date, String format) throws ParseException{
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(sdf.parse(date));
		return calendar;
	}
	
	public static XMLGregorianCalendar XMLGregorianCalendarFormat(String date, String format) throws ParseException, DatatypeConfigurationException{
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		Date d = sdf.parse(date);
		GregorianCalendar gcal =new GregorianCalendar();
		gcal.setTime(d);
		return DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
	}
	
	public static Date convertToDate(XMLGregorianCalendar cal)throws Exception{
		GregorianCalendar ca = cal.toGregorianCalendar();
        return ca.getTime();
	}
	
	public static String XMLGregorianCalendartoStr(XMLGregorianCalendar cal,String format)throws Exception{
		GregorianCalendar ca = cal.toGregorianCalendar();
		return toStrDate(ca.getTime(),"yyyy-MM-dd");
	}
	
	public static Date format(String date) throws ParseException {
		return format(date, yyyyMMddHHmmss);
	}
	
	// 2016-12-12
	public static boolean isBefore(String date1, String date2) {
		return isBefore(date1, date2, yyyy_MM_dd);
	}
	
	public static boolean isBefore(String date1, String date2, String format) {
		if (ObjectUtil.noText(date1) || ObjectUtil.noText(date2)) {
			return false;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			Date dateNum1 = sdf.parse(date1);
			Date dateNum2 = sdf.parse(date2);
			return dateNum1.before(dateNum2);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}
	
	public static int getAge(Date birthDay) throws Exception { 
        //获取当前系统时间
        Calendar cal = Calendar.getInstance(); 
        //如果出生日期大于当前时间，则抛出异常
        if (cal.before(birthDay)) { 
            throw new IllegalArgumentException( 
                "The birthDay is before Now.It's unbelievable!"); 
        } 
        //取出系统当前时间的年、月、日部分
        int yearNow = cal.get(Calendar.YEAR); 
        int monthNow = cal.get(Calendar.MONTH); 
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); 
         
        //将日期设置为出生日期
        cal.setTime(birthDay); 
        //取出出生日期的年、月、日部分  
        int yearBirth = cal.get(Calendar.YEAR); 
        int monthBirth = cal.get(Calendar.MONTH); 
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH); 
        //当前年份与出生年份相减，初步计算年龄
        int age = yearNow - yearBirth; 
        //当前月份与出生日期的月份相比，如果月份小于出生月份，则年龄上减1，表示不满多少周岁
        if (monthNow <= monthBirth) { 
            //如果月份相等，在比较日期，如果当前日，小于出生日，也减1，表示不满多少周岁
            if (monthNow == monthBirth) { 
                if (dayOfMonthNow < dayOfMonthBirth) age--; 
            }else{ 
                age--; 
            } 
        } 
        System.out.println("age:"+age); 
        return age; 
    }	
	
	public static void main(String[] args) {
		//System.out.println(toStrDate("2016-09-09", "18:01"));
		String date = "2017-07-05";
		try {
			XMLGregorianCalendar C  = DateUtil.XMLGregorianCalendarFormat(date,"yyyy-MM-dd");
			System.out.println(C);
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (DatatypeConfigurationException e) {
			e.printStackTrace();
		}
	}
}
